home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 21 / CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso / CUCD / Programming / Python-1.4 / Source / Amiga / Python_netlib / lineread.c < prev    next >
C/C++ Source or Header  |  1998-01-31  |  11KB  |  404 lines

  1. RCS_ID_C="$Id: lineread.c,v 4.2 1994/09/30 00:35:04 jraja Exp $";
  2. /*
  3.  *      lineread.c - functions to read lines from sockets effectively
  4.  *
  5.  *      Copyright © 1994 AmiTCP/IP Group, 
  6.  *                       Network Solutions Development Inc.
  7.  *                       All rights reserved.
  8.  */
  9.  
  10. /*
  11.  * since charRead is a macro package and having no `.c' -file, it's
  12.  * documentation is added here
  13.  */
  14.  
  15. /****** net.lib/charRead ****************************************************
  16.  
  17.     NAME
  18.     charRead -- read characters from socket one by one.
  19.  
  20.     SYNOPSIS
  21.     initCharRead(rc, fd)
  22.  
  23.     void initCharRead(struct CharRead *, int);
  24.  
  25.  
  26.     character = charRead(rc)
  27.  
  28.     int charRead(struct CharRead *);
  29.  
  30.  
  31.     DESCRIPTION
  32.     charRead is a macro package which return characters one by one 
  33.     from given socket input stream. The socket where data is to be read
  34.     is set by calling initCharRead(): rc is the pointer to charread
  35.     structure previously allocated. fd is the (socket) descriptor where
  36.     reading is to be done.
  37.  
  38.     charRead() returns the next character from input stream or one of
  39.     the following:
  40.  
  41.     RC_DO_SELECT    (-3)    - read input buffer is returned. Do select
  42.                   before next call if you don't want charread
  43.                   to block.
  44.  
  45.     RC_EOF          (-2)    - end-of-file condition has occurred.
  46.  
  47.     RC_ERROR        (-1)    - there has been an error while filling new
  48.                   charread buffer. Check the value of Errno()
  49.  
  50.     NOTE
  51.     Always use variable of type int to store return value from charRead()
  52.     since the numeric value of characters returned may vary between
  53.     0 -255 (or even greater). As you may know, -3 equals 253 if of type
  54.     unsigned char.
  55.  
  56.     EXAMPLE
  57.     \*
  58.      * This piece of code shows how to use charread with select()
  59.      *\
  60.     #include <sys/types.h>
  61.     #include <sys/socket.h>
  62.     #include <charread.h>
  63.  
  64.     main_loop(int sock)
  65.     {
  66.       struct CharRead rc;
  67.       fd_set readfds;
  68.       int c;
  69.  
  70.       initCharRead(&rc, sock);
  71.  
  72.       FD_ZERO(&readfds);
  73.  
  74.       while(1) {
  75.         FD_SET(sock, &readfds);     
  76.  
  77.         if (select(sock + 1. &readfds, NULL, NULL, NULL)) < 0) {
  78.           perror("select");
  79.           break;
  80.         }
  81.         if (FD_ISSET(sock, &readfds)) {
  82.           while((c = charRead(&rc)) >= 0)
  83.         handle_next_input_character(c);
  84.           if (c == RC_EOF)
  85.         break;
  86.           if (c == RC_ERROR) {
  87.         perror("charRead");
  88.         break;
  89.           }
  90.         }
  91.       }
  92.     }
  93.  
  94.      PORTABILITY
  95.     The source file charread.h should be able to be used in 
  96.     UNIX programs as is.
  97.  
  98.      SEE ALSO
  99.     lineRead(), bsdsocket.library/recv()
  100. *****************************************************************************
  101. *
  102. */
  103.  
  104.  
  105. /****** net.lib/lineRead *****************************************************
  106.  
  107.     NAME
  108.         lineRead -- read newline terminated strings from socket
  109.  
  110.     SYNOPSIS
  111.         initLineRead(rl, fd, lftype, bufsize)
  112.  
  113.         void initLineRead(struct LineRead *, int, int, int);
  114.  
  115.  
  116.         length = lineRead(rl)
  117.  
  118.         int lineread(struct LineRead *);
  119.  
  120.  
  121.     FUNCTION
  122.         lineRead() reads newline terminated strings from given descriptor
  123.         very efficiently. All the options needed are set by calling
  124.         initLineRead(): rl is the pointer to lineread structure previously
  125.         allocated. fd is the (socket) descriptor where reading is to be
  126.         done. lftype can have following 3 values:
  127.  
  128.             RL_LFNOTREQ - Newline terminated strings are returned unless
  129.                           there is no newlines left in currently buffered
  130.                           input. In this case remaining buffer is returned.
  131.  
  132.             RL_LFREQLF  - If there is no newlines left in currently buffered
  133.                           input the remaining input data is copied at the
  134.                           start of buffer. Caller is informed that next
  135.                           call will fill the buffer (and it may block).
  136.                           Lines are always returned with newline at the end
  137.                           unless the string is longer than whole buffer.
  138.  
  139.             RL_LFREQNUL  - Like LF_REQLF, but remaining newline is removed.
  140.                           Note here that lenght is one longer that actual
  141.                           string length since line that has only one
  142.                           newline at the end would return length as 0
  143.                           which indigate string incomplete condition.
  144.  
  145.         bufsize is used to tell lineread how big the receive buffer is.
  146.         always put RL_BUFSIZE here since that value is used to determine
  147.         the memory allocated for the buffer. This option is given to you
  148.         so you may decide to use different buffer size than the default
  149.         1024.
  150.  
  151.         lineRead() returns the newline terminated string in rl_line field
  152.         of lineread structure. Return values of lineRead() are:
  153.  
  154.              1 - RL_BUFSIZE     - normal length of returned string.
  155.  
  156.              0                  - If zero is returned just after select(),
  157.                                   end-of-file condition has occurred.
  158.                                   Otherwise string is not completed yet.
  159.                                   Make sure you call select() (or use non-
  160.                                   blocking IO) if you don't want next call
  161.                                   to block.
  162.  
  163.             -1                  - if rl_Line field of lineread structure
  164.                                   is NULL, it indicates error condition.
  165.                                   If rl_Line points to start of string
  166.                                   buffer, input string has been longer
  167.                                   than buffer. In this case rl_Line points
  168.                                   to zero terminated string of length
  169.                                   RL_BUFSIZE.
  170.  
  171.         You may modify the zero terminated string returned by lineRead() in
  172.         any way, but memory around the string is private lineread memory.
  173.  
  174.     EXAMPLE
  175.         \*
  176.          * The following code shows how to use lineread with select()
  177.          *\
  178.         #ifdef USE_LOW_MEMORY_BUFFER
  179.         #define RL_BUFSIZE 256
  180.         #endif
  181.  
  182.         #include <sys/types.h>
  183.         #ifdef _AMIGA
  184.         #include <bsdsocket.h>
  185.         #endif
  186.         #include <lineread.h>
  187.  
  188.         #define NULL 0
  189.  
  190.         ...
  191.  
  192.         main_loop(int sock)
  193.         {
  194.           struct LineRead * rl;
  195.           int length;
  196.           fd_set reafdfs;
  197.  
  198.           if (rl = (struct LineRead *)AllocMem(sizeof (*rl), 0)) {
  199.  
  200.             initLineRead(rl, sock, LF_REQLF, RL_BUFSIZE);
  201.  
  202.             FD_ZERO(&readfds);
  203.  
  204.             while(1) {
  205.               FD_SET(sock, &readfds);
  206.  
  207.               if (select(sock + 1, &readfds, NULL, NULL, NULL)) < 0) {
  208.                 perror("select");
  209.                 break;
  210.               }
  211.               if (FD_ISSET(sock, &readfds))
  212.                 if ((length = lineRead(rl)) == 0) \* EOF *\
  213.                   break;
  214.                 do {
  215.                   if (length > 0)
  216.                     write(1, rl->rl_Line, length); \* stdout. write() for *\
  217.                                                    \* speed demonstration *\
  218.                   else { \* length == -1 *\
  219.                     if (rl->rl_Line == NULL); {
  220.                       perror("lineRead");
  221.                       break;
  222.                     }
  223.                     else {
  224.                       fprintf(stderr, "lineread input buffer overflow!\n");
  225.                       write(1, rl->rl_Line, RL_BUFSIZE);
  226.                       write(1, "\n", 1);
  227.                     }
  228.                   }
  229.                 } while ((length = lineRead(rl)) != 0); \* 0 -> do select() *\
  230.             }
  231.           FreeMem(rl, sizeof (*rl);
  232.           }
  233.           else
  234.             fprintf("AllocMem: Out Of memory\n");
  235.         }
  236.  
  237.      PORTABILITY
  238.         The source modules lineread.c and lineread.h should compile
  239.         in UNIX machines as is.
  240.  
  241.      SEE ALSO
  242.         charRead(), bsdsocket.library/recv()
  243.  
  244. ******************************************************************************
  245. */
  246.  
  247. #include "lineread.h"
  248.  
  249. #ifdef _AMIGA
  250. extern struct Library * SocketBase;
  251. #define READ(a, b, c) recv(a, b, c, 0)
  252. #if __SASC
  253. #include <proto/socket.h>
  254. #elif __GNUC__
  255. #include <inline/socket.h>
  256. #endif
  257. #else /* not _AMIGA */
  258. #define READ(a, b, c) read(a, b, c)
  259. #endif /* _AMIGA */
  260.  
  261. #ifndef NULL
  262. #define NULL 0
  263. #endif
  264.  
  265. #ifndef FALSE
  266. #define FALSE 0
  267. #endif
  268.  
  269. #ifndef TRUE
  270. #define TRUE 1
  271. #endif
  272.  
  273. #ifndef __CONCAT
  274. #if defined (__STDC__) || defined (__cplusplus)
  275. #define __CONCAT(x,y) x ## y
  276. #else
  277. #define __CONCAT(x,y) x/**/y
  278. #endif
  279. #endif /* __CONCAT not defined */  
  280.   
  281. #define RLP(field) __CONCAT(rl->rl_Private.rlp_,field)
  282.  
  283.  
  284. #if defined (__STDC__) || defined (__cplusplus)
  285.  
  286. int lineRead(struct LineRead * rl)
  287.  
  288. #else
  289.  
  290. int lineRead(rl)
  291.      struct LineRead * rl;
  292.  
  293. #endif
  294. {
  295.   int i;
  296.   
  297.   if (RLP(Bufpointer) == RLP(Howlong))
  298.  
  299.     if (RLP(Selected)) {
  300.  
  301.       if (RLP(Line_completed))
  302.     RLP(Startp) = RLP(Bufpointer) = 0;
  303.  
  304.       if ((i = READ(rl->rl_Fd,
  305.             RLP(Buffer) + RLP(Bufpointer),
  306.             RLP(Buffersize) - RLP(Bufpointer))) <= 0) {
  307.     /*
  308.      * here if end-of-file or on error. set Howlong == Bufpointer
  309.      * so if non-blocking I/O is in use next call will go to READ()
  310.      */
  311.     RLP(Howlong) = RLP(Bufpointer);
  312.     rl->rl_Line = NULL;            
  313.     return i;
  314.       }
  315.       else
  316.     RLP(Howlong) = RLP(Bufpointer) + i;
  317.     }
  318.     else /* Inform user that next call may block (unless select()ed) */ 
  319.       {
  320.     RLP(Selected) = TRUE;
  321.     return 0;
  322.       }
  323.   else /* Bufpointer has not reached Howlong yet. */
  324.     {
  325.       RLP(Buffer)[RLP(Bufpointer)] = RLP(Saved);
  326.       RLP(Startp) = RLP(Bufpointer);
  327.     }
  328.  
  329.   /*
  330.    * Scan read string for next newline.
  331.    */
  332.   while (RLP(Bufpointer) < RLP(Howlong))
  333.     if (RLP(Buffer)[RLP(Bufpointer)++] == '\n')
  334.       goto Skip;
  335.  
  336.   /*
  337.    * Here if Bufpointer == Howlong.
  338.    */
  339.   if (rl->rl_Lftype != RL_LFNOTREQ) {
  340.     RLP(Selected) = TRUE;
  341.  
  342.     if (RLP(Bufpointer) == RLP(Buffersize)) {
  343.       /*
  344.        * Here if Bufpointer reaches end-of-buffer.
  345.        */
  346.       if (RLP(Startp) == 0) { /* (buffer too short for whole string) */
  347.     RLP(Line_completed) = TRUE;
  348.     rl->rl_Line = RLP(Buffer);
  349.     RLP(Buffer)[RLP(Bufpointer)] = '\0';
  350.     return -1;
  351.       }
  352.       /*
  353.        * Copy partial string to start-of-buffer and make control ready for
  354.        * filling rest of buffer when next call to lineRead() is made
  355.        * (perhaps after select()).
  356.        */
  357.       for (i = 0; i < RLP(Buffersize) - RLP(Startp); i++)
  358.     RLP(Buffer)[i] = RLP(Buffer)[RLP(Startp) + i];
  359.       RLP(Howlong)-= RLP(Startp);
  360.       RLP(Bufpointer) = RLP(Howlong);
  361.       RLP(Startp) = 0;
  362.     }
  363.     
  364.     RLP(Line_completed) = FALSE;
  365.     return 0;
  366.   }
  367.  
  368.  Skip:
  369.   RLP(Line_completed) = TRUE;
  370.   if (rl->rl_Lftype == RL_LFREQNUL)
  371.     RLP(Buffer)[RLP(Bufpointer) - 1] = '\0';
  372.   RLP(Saved) = RLP(Buffer)[RLP(Bufpointer)];
  373.   RLP(Buffer)[RLP(Bufpointer)] = '\0';
  374.   RLP(Selected) = FALSE;
  375.   rl->rl_Line = RLP(Buffer) + RLP(Startp);
  376.  
  377.   return (RLP(Bufpointer) - RLP(Startp));
  378. }
  379.  
  380. #undef READ      
  381.  
  382. #if defined (__STDC__) || defined (__cplusplus)
  383.       
  384. void initLineRead(struct LineRead * rl, int fd, int lftype, int buffersize)
  385.       
  386. #else
  387.  
  388. int initLineRead(rl, fd, lftype, buffersize)
  389.       struct LineRead * rl;
  390.       int fd;
  391.       int lftype;
  392.       int buffersize;
  393.   
  394. #endif
  395. {      
  396.   rl->rl_Fd     = fd;
  397.   rl->rl_Lftype = lftype;
  398.  
  399.   RLP(Bufpointer) = RLP(Howlong) = 0;
  400.   RLP(Selected) = RLP(Line_completed) = TRUE;
  401.  
  402.   RLP(Buffersize) = buffersize;
  403. }
  404.